package com.xuanyue.db.xuan.core.table.expr;

import java.nio.ByteBuffer;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import com.xuanyue.db.xuan.core.exception.SQLException;

public class ExprValue {

	private static ExprValue NULLValue = new ExprValue();
	private ExprValueType type;
	private Object value;
	
	public ExprValue() {}
	public ExprValue(ExprValueType type) {
		this.type = type;
	}
	public ExprValue(ExprValueType type,Object value) {
		this.type = type;
		this.value = value;
	}
	public ExprValueType getType() {
		return type;
	}
	public void setType(ExprValueType type) {
		this.type = type;
	}
	@SuppressWarnings("unchecked")
	public <T>T getValue() {
		return (T)value;
	}
	public void setValue(Object value) {
		this.value = value;
	}
	
	
	
	@Override
	public String toString() {
		if(value==null) {
			if(type==null) {
				return "type:null  value:null";
			}else {
				return String.format("type:null  value:%s", value.toString());
			}
		}else {
			if(type==null) {
				return String.format("type:null  value:%s", value.toString());
			}else {
				return String.format("type:%s  value:%s",type, value.toString());
			}
		}
	}


	public void saveInto(ByteBuffer data) {
		/*
		DATE(1),STRING(2),
	//NUMBER(3),
	
	TRANSATTR(3),NULL(4),BOOLEAN(5),ARRAY(6),
	INT(7),LONG(8),FLOAT(9),
	MAP(10),BYTEARRAY(11);
		*/
		
		data.putInt(type.getType() );
		switch(type) {
			case DATE:
			case LONG:
				data.putLong( ((Date)value).getTime() );
				break;
			case STRING:
				byte[] ts = this.getValue();
				data.putInt(ts.length);
				data.put(ts);
				break;
			case NULL:
				break;
			case BOOLEAN:
				data.putInt( ((boolean)value)?1:0 );
				break;
			case INT:
				data.putInt( (int)value);
				break;
			case FLOAT:
				data.putFloat( (float)value  );
				break;
			case BYTEARRAY:
				byte[] bs = this.getValue();
				data.putInt(bs.length);
				data.put(bs);
				break;
			case ARRAY:
				List<ExprValue> el = this.getValue();
				data.putInt( el.size() );
				for(ExprValue e:el) {
					e.saveInto(data);
				}
				break;
			case MAP:
				Map<String,ExprValue> em = this.getValue();
				data.putInt( em.size() );
				for(Entry<String,ExprValue> en:em.entrySet()) {
					byte[] sb = en.getKey().getBytes();
					data.putInt(sb.length);
					data.put(sb );
					en.getValue().saveInto(data);
				}
				break;
			case TRANSATTR:
				throw new SQLException("the type TRANSATTR can not save to ByteBuffer");
		}
	}
	

	static {
		NULLValue.setType(ExprValueType.NULL);
	}
	/**
	 * 空值
	 * @return
	 * @author 解观海
	 * @date 2020年12月27日
	 */
	public static ExprValue getNULLExprValue() {
		return NULLValue;
	}
}
